LINQ: Fixes array.Contains() for .NET 10 MemoryExtensions#5585
Closed
kirankumarkolli wants to merge 6 commits intomasterfrom
Closed
LINQ: Fixes array.Contains() for .NET 10 MemoryExtensions#5585kirankumarkolli wants to merge 6 commits intomasterfrom
kirankumarkolli wants to merge 6 commits intomasterfrom
Conversation
In .NET 10, array.Contains() may resolve to MemoryExtensions.Contains(ReadOnlySpan<T>, T) instead of Enumerable.Contains. Since ReadOnlySpan doesn't implement IEnumerable, the existing IsEnumerable() check fails. Changes: - Add IsMemoryExtensionsMethod() helper to detect MemoryExtensions methods - Route MemoryExtensions.Contains to ArrayBuiltinFunctions for proper SQL translation - Add unit tests for MemoryExtensions detection Fixes #5518
- TestMemoryExtensionsContainsExpressionDetection: Verifies MemoryExtensions.Contains<T>(ReadOnlySpan<T>, T) is properly detected - TestBuiltinFunctionVisitorMemoryExtensionsCheck: Simulates .NET 10 expression and validates our fix - TestEnumerableContainsNotDetectedAsMemoryExtensions: Ensures Enumerable.Contains is unaffected These tests programmatically create the expression trees that .NET 10 generates for array.Contains(), verifying the fix handles them correctly.
kirankumarkolli
commented
Feb 2, 2026
…uction Addresses review comment: replaced superficial type-name checks with a test that constructs an actual MemoryExtensions.Contains MethodCallExpression and verifies the DeclaringType matches. Removed redundant tests, kept array IsEnumerable and Enumerable negative check. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
|
@kirankumarkolli Minh had a pr open to address this: He ran into some issues, since for testing it needed projects to be upgraded to .NET 9 - partly why it's not merged. |
Contributor
|
Hi @kirankumarkolli — this PR has been idle for ~36 days. What's the current ETA / status? Flagging as part of an open-PR cleanup pass; if it's no longer being pursued we can close it. No auto-close — just looking for a status update. |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
Contributor
|
Closed in favor of #5819 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
🤖 This PR was authored by GitHub Copilot as part of an automated issue triage and resolution workflow.
Fixes #5518
In .NET 10,
array.Contains(x)may resolve toMemoryExtensions.Contains(ReadOnlySpan<T>, T)instead ofEnumerable.Contains. SinceReadOnlySpan<T>doesn't implementIEnumerable, the existing check inBuiltinFunctionVisitorfails withNotSupportedException.Issue Summary
Root Cause Analysis
Code Path
Root Cause
In .NET 10, the C# compiler resolves
array.Contains(item)toMemoryExtensions.Contains<T>(ReadOnlySpan<T>, T)instead ofEnumerable.Contains<T>(IEnumerable<T>, T).The LINQ translator checks
declaringType.IsEnumerable()to route extension methods, butReadOnlySpan<T>(the first parameter type ofMemoryExtensions.Contains) doesn't implementIEnumerable<T>, causing the method to be unrecognized.This is a forward compatibility issue - existing code works in .NET 8/9 but fails in .NET 10+ previews.
Changes Made
Files Modified
BuiltinFunctionVisitor.csIsMemoryExtensionsMethod()helper and routing logicLinqMemoryExtensionsTests.csCode Changes
IsMemoryExtensionsMethod()helper - Detects when method is fromSystem.MemoryExtensionsby checkingDeclaringType.FullNameArrayBuiltinFunctionswhich already handles both 1-arg and 2-arg Contains signaturesGenerated Output (Before/After)
Before (incorrect):
After (correct):
Testing
Local Test Results
Breaking Changes
None - This is an additive fix that enables previously unsupported scenarios.
Checklist
Generated by GitHub Copilot CLI Agent